package com.asus.sun.extend.nodeAttr;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.editor.constants.StencilConstants;
import org.flowable.editor.language.json.converter.*;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Lenovo on 2019/8/12.
 */
public class BruceUserTaskJsonConverter extends UserTaskJsonConverter implements FormAwareConverter, FormKeyAwareConverter {
    private static final Logger LOGGER = LoggerFactory.getLogger(BruceUserTaskJsonConverter.class);

    public static final String IS_EDITDATA = "iseditdata";
    /*
     * 扩展属性1 -- 节点id
     * 对应  stencilset/stencilset_bpmn.json 中的  extend_task_node_id
     */
    public static final String EXTEND_ATTR_1 = "extend_task_node_id";

    /*
   * 扩展属性id --- 阶段id
   * 对应  stencilset/stencilset_bpmn.json 中的  extend_task_stage_id
   */
    public static final String EXTEND_ATTR_2 = "extend_task_stage_id";

    /*
      * 扩展属性id - 审批是否去重
      * 对应  stencilset/stencilset_bpmn.json 中的  extend_task_stage_id
      */
    public static final String EXTEND_ATTR_3 = "node_approval_distinct_id";

    /*
     * 自定义回退节点编号地址
     * 对应  stencilset/stencilset_bpmn.json 中的  extend_task_stage_id
     */
    public static final String EXTEND_ATTR_4 = "custom_task_return_node_id";


    @Override
    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode,Map<String, JsonNode> shapeMap) {
        UserTask flowElement = (UserTask) super.convertJsonToElement(elementNode, modelNode, shapeMap);
        LOGGER.info("===调用BruceUserTaskJsonConverter.convertJsonToElement(),生成自定义属性 ");
        List<CustomProperty> customProperties = new ArrayList<>();
        // 自定义属性扩展 节点可编辑
        String isEditdata = getPropertyValueAsString(IS_EDITDATA, elementNode);
        if (StringUtils.isNotBlank(isEditdata)) {
            CustomProperty editData = this.createProperty(IS_EDITDATA, isEditdata);
            customProperties.add(editData);
        }
        // 扩展 节点类型
        String attr1 = getPropertyValueAsString(EXTEND_ATTR_1, elementNode);
        if (StringUtils.isNotBlank(attr1)) {
            CustomProperty nodeType = this.createProperty(EXTEND_ATTR_1, attr1);
            customProperties.add(nodeType);
        }
        // 扩展 节点类型
        String attr2 = getPropertyValueAsString(EXTEND_ATTR_2, elementNode);
        if (StringUtils.isNotBlank(attr2)) {
            CustomProperty nodeType = this.createProperty(EXTEND_ATTR_2, attr2);
            customProperties.add(nodeType);
        }

        // 扩展 节点类型 - 审批是否去重
        String nodeApprovalDistinctStr = getPropertyValueAsString(EXTEND_ATTR_3, elementNode);
        CustomProperty nodeType = this.createProperty(EXTEND_ATTR_3, getBooleanByString(nodeApprovalDistinctStr)+"");
        customProperties.add(nodeType);


        // 自定义回退节点编号地址
        String custom_task_return_node_id = getPropertyValueAsString(EXTEND_ATTR_4, elementNode);
        if (StringUtils.isNotBlank(custom_task_return_node_id)) {
            CustomProperty task_return_nodeType = this.createProperty(EXTEND_ATTR_4, custom_task_return_node_id);
            customProperties.add(task_return_nodeType);
        }

        if (CollectionUtils.isNotEmpty(customProperties)) {
            flowElement.setCustomProperties(customProperties);
        }
        return flowElement;
    }

    /**
     * 创建自定义属性
     *
     * @param propertyName  属性名称
     * @param propertyValue 属性值
     */
    private CustomProperty createProperty(String propertyName, String propertyValue) {
        CustomProperty customProperty = new CustomProperty();
        customProperty.setId(propertyName);
        customProperty.setName(propertyName);
        customProperty.setSimpleValue(propertyValue);
        return customProperty;
    }

    public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                 Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void setCustomTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                      Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        removeTypes(convertersToBpmnMap,convertersToJsonMap);
        fillTypes(convertersToBpmnMap,convertersToJsonMap);
    }

    public static void removeTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                   Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.remove(UserTask.class);
        convertersToBpmnMap.remove(StencilConstants.STENCIL_TASK_USER);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(StencilConstants.STENCIL_TASK_USER, BruceUserTaskJsonConverter.class);
    }

    public static void fillBpmnTypes(
            Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(UserTask.class, BruceUserTaskJsonConverter.class);
    }

    @Override
    public void convertToJson(BaseElement baseElement, ActivityProcessor processor, BpmnModel model, FlowElementsContainer container, ArrayNode shapesArrayNode, double subProcessX, double subProcessY){
        super.convertToJson(baseElement, processor, model, container, shapesArrayNode, subProcessX, subProcessY);
    }


    public static boolean getBooleanByString(String value){
        if(StringUtils.isNotBlank(value)){
            if("true".equals(value)||"True".equals(value)||"TRUE".equals(value)){
                return true;
            }
        }
        return false;
    }
}
